package com.hzhr.iot.meterplan.aop;

import com.hzhr.iot.core.constant.HzhrAttrNames;
import com.hzhr.iot.core.constant.HzhrHeaderNames;
import com.hzhr.iot.core.util.HzhrJsonUtil;
import com.hzhr.iot.core.util.HzhrStringUtils;
import com.hzhr.iot.core.util.HzhrTypeUtil;
import com.hzhr.iot.log.sdk.model.log.LogModel;
import com.hzhr.iot.log.sdk.model.log.LogPostModel;
import com.hzhr.iot.log.sdk.service.Log_LogService;
import com.hzhr.iot.meterplan.Global;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;


@Aspect
@Component
@Order(1)
public class LogAspect {
    @Autowired
    HttpServletRequest request;
    @Autowired
    Log_LogService log_logService;
    @Autowired
    Global global;

    @Value("${spring.application.name}")
    String serviceName;

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Pointcut("execution(* com.hzhr.iot.meterplan.controller..*(..))")
    public void logPointCut() {
    }

    @Before("logPointCut()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
    }

    @AfterReturning(returning = "ret", pointcut = "logPointCut()")
    public void doAfterReturning(Object ret) throws Throwable {
    }

    @Around("logPointCut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        //region 生成日志模型
        String token = request.getHeader("token");
        String token1 = HzhrTypeUtil.object2string(request.getAttribute("token"));
        if (!StringUtils.isEmpty(token1)) token = token1;

        String globalToken = global.getToken();
        LogModel log = new LogModel();

        Object args = joinPoint.getArgs();
        if (args != null) {
            log.setHttpReqBody(HzhrJsonUtil.object2json(args));
        }

        String transactionId = request.getHeader(HzhrHeaderNames.TRANSACTION_ID);
        if (StringUtils.isEmpty(transactionId)) {
            transactionId = HzhrStringUtils.getGUID();
        } else {
            if (StringUtils.isEmpty(token) || !globalToken.contains(token)) {
                transactionId = HzhrStringUtils.getGUID();
            }
        }
        log.setTransactionId(transactionId);
        request.setAttribute(HzhrHeaderNames.TRANSACTION_ID, transactionId);

        String transactionType = "1";//事务类型默认为用户操作
        if (!StringUtils.isEmpty(token) && globalToken.contains(token)) {
            if (!StringUtils.isEmpty(request.getHeader(HzhrHeaderNames.TRANSACTION_TYPE))) {
                transactionType = request.getHeader(HzhrHeaderNames.TRANSACTION_TYPE);
            }
        }
        log.setTransactionType(transactionType);
        request.setAttribute(HzhrHeaderNames.TRANSACTION_TYPE, transactionType);

        String uri = request.getRequestURI();
        log.setUri(uri);

        log.setServiceName(serviceName);

        log.setHttpMethod(request.getMethod());
        log.setExistException("0");
        request.setAttribute(HzhrAttrNames.LOG, log);
        //endregion

        //region 执行方法
        ResponseEntity response = (ResponseEntity)joinPoint.proceed();
        Object responseBody = response.getBody();
        HttpStatus httpStatus = response.getStatusCode();
        //endregion

        //region 写日志
        LogPostModel logPostModel = HzhrJsonUtil.convertObjectType(log, LogPostModel.class);
        if (token != null) {
            logPostModel.setUserId(HzhrTypeUtil.object2integer(request.getAttribute(HzhrHeaderNames.USER_ID)));
            logPostModel.setUserName(HzhrTypeUtil.object2string(request.getAttribute(HzhrHeaderNames.USER_NAME)));
            logPostModel.setUserCode(HzhrTypeUtil.object2string(request.getAttribute(HzhrHeaderNames.USER_CODE)));
        }
        logPostModel.setHttpRespBody(HzhrJsonUtil.object2json(responseBody));
        logPostModel.setHttpRespCode(httpStatus.value());
        log_logService.post(new HashMap<>(), logPostModel, new HashMap<>());
        //endregion

        return response;
    }
}